
//
// Copyright (c) 2008, the /*jupiter jazz*/ group
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the /*jupiter jazz*/ group nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY the /*jupiter jazz*/ group ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL the /*jupiter jazz*/ group BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

// maketiledexr headers.
#include "commandline.h"

// classlib headers.
#include "classlib/exception.h"
#include "classlib/progressiveexrimagefilereader.h"
#include "classlib/progressiveexrimagefilewriter.h"
#include "classlib/tile.h"

// OpenEXR headers.
#include "openexr/ImfChannelList.h"
#include "openexr/ImfFrameBuffer.h"
#include "openexr/ImfHeader.h"
#include "openexr/ImfPixelType.h"
#include "openexr/ImfTileDescription.h"

// Standard headers.
#include <iostream>
#include <cstddef>

using namespace std;

int main(int argc, const char* argv[])
{
    // Parse program command line.
    CommandLine cl;
    cl.parse(argc, argv);

    // Retrieve the tile size.
    size_t tile_width = 32;
    size_t tile_height = 32;
    if (cl.m_tile_size.found())
    {
        const int tw = cl.m_tile_size.values()[0];
        const int th = cl.m_tile_size.values()[1];
        if (tw > 0 && th > 0)
        {
            tile_width = static_cast<size_t>(tw);
            tile_height = static_cast<size_t>(th);
        }
        else
        {
            cerr << "invalid tile size, using default size "
                 << tile_width << "x" << tile_height
                 << " pixels" << endl;
        }
    }

    try
    {
        // Open the input file.
        foundation::ProgressiveEXRImageFileReader reader(tile_width, tile_height);
        reader.open(cl.m_filenames.values()[0].c_str());

        // Read canvas properties from the input file.
        foundation::CanvasProperties props;
        reader.read_canvas_properties(props);

        // Open the output file.
        foundation::ProgressiveEXRImageFileWriter writer;
        writer.open(cl.m_filenames.values()[1].c_str(), props);

        // Copy the tiles.
        for (size_t y = 0; y < props.m_tile_count_y; ++y)
        {
            // Print a progress message.
            if (cl.m_progress_messages.found())
            {
                cerr << "processing tile row "
                     << y + 1 << "/" << props.m_tile_count_y
                     << "..." << endl;
            }

            for (size_t x = 0; x < props.m_tile_count_x; ++x)
            {
                // Read the tile.
                const foundation::Tile* tile = reader.read_tile(x, y);
                if (tile == 0)
                    throw foundation::Exception("couldn't read a tile");

                // Write the tile.
                writer.write_tile(*tile, x, y);

                // Deallocate the tile.
                delete tile;
            }
        }

        // Close the files.
        writer.close();
        reader.close();
    }
    catch (const foundation::Exception& e)
    {
        cerr << "fatal: " << e.what() << endl;
        return 1;
    }

    return 0;
}
